package org.huhu.mercury.common;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.TreeSet;

import org.apache.commons.codec.digest.DigestUtils;
import org.huhu.mercury.common.exception.ResultInfoException;

import com.alibaba.fastjson.JSON;

/**
 * @Description: 用于http操作时签名的生成
 * @author yfx
 */
public class HttpSignUtils {
	
	/**失效时长。默认*/
	public static final long EXPIRE_LENGTH=1000*60*30;
	/**
	 * 通过请求参数生成请求url
	 * @param bodyParams 请求额外参数
	 * @param timestamp 时间戳
	 * @param appKey client的appkey
	 * @param appSecret client的appSecret
	 * @return
	 */
	public static String createHttpUrl(Map<String, Object> bodyParams,long timestamp,String appKey,String appSecret){
		String sign=createHttpSign(bodyParams, timestamp, appKey, appSecret);
		StringBuffer sb=new StringBuffer();
		sb.append("timestamp").append("=").append(timestamp).append("&");
		for(String key:bodyParams.keySet()){
			try {
				sb.append(key).append("=").append(URLEncoder.encode(trim(bodyParams.get(key)), "utf-8")).append("&");
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
		}
		sb.append("sign").append("=").append(sign);
		return sb.toString();
	}
	
	/**
	 * 生成签名sign|如果是文件上传操作建议使用post方式操作
	 * @param bodyParams 请求额外参数
	 * @param timestamp 时间戳
	 * @param appKey client的appkey
	 * @param appSecret client的appSecret
	 * @return
	 */
	public static String createHttpSign(Map<String, Object> bodyParams,long timestamp,String appKey,String appSecret){
		String str=getParams(bodyParams);
		str+="timestamp"+timestamp;
		str+="appKey"+appKey;
		str+="appSecret"+appSecret;
		String sign=DigestUtils.sha1Hex(str);
		return sign;
	}
	
	public static void checkHttpSign(Map<String, Object> bodyParams,long timestamp,String appKey,String appSecret,String sign){
		checkHttpSign(bodyParams, timestamp, appKey, appSecret, sign,EXPIRE_LENGTH);
	}
	
	public static void checkHttpSign(Map<String, Object> bodyParams,long timestamp,String appKey,String appSecret,String sign,long expireLength){
		//已达失效时长
		if(timestamp+expireLength<System.currentTimeMillis()){
			throw new ResultInfoException("expire","请求已失效。");
		}
		String sign1=createHttpSign(bodyParams, timestamp, appKey, appSecret);
		if(!sign1.equalsIgnoreCase(sign)){
			throw new ResultInfoException("checkError","签名验证不能通过。");
		}
	}
	
	/**
	 * 返回请求参数
	 * @param request
	 * @return
	 */
	private static String getParams(Map<String,Object> maps){
		String resultStr="";
		if(maps==null) return resultStr;
		for(String set:new TreeSet<String>(maps.keySet())){
			String val=trim(maps.get(set));
			resultStr+=set+val;
			maps.put(set, val);
		}
		return resultStr;
	}
	
	/**
	 * 去空，null->''
	 * @param str
	 * @return
	 */
	private static String trim(Object str) {
		if(str==null){
			return "";
		}else if(str instanceof String){
			if ("null".equals(str.toString().trim())) {
				return "";
			} else {
				return str.toString().trim();
			}
		}else{
			return JSON.toJSONString(str);
		}
	}
	
	public static void main(String[] args) {
		//21470ab7721f3edea9c3a1c3b2f3ee4b2c4a5225
		//ca417018ffa2d813c30dcb959e6881494a404cbb
	}
}
